package com.hzdp.netty.aio;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.CountDownLatch;

import org.apache.log4j.Logger;

public class AsyncTimeClientHandler implements Runnable {

	protected static Logger logger = Logger.getLogger(AsyncTimeClientHandler.class);

	private int port;
	private String host;

	private AsynchronousSocketChannel channel;
	private CountDownLatch latch;

	public AsyncTimeClientHandler(String host, int port) {
		this.host = host;
		this.port = port;

		try {
			channel = AsynchronousSocketChannel.open();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		latch = new CountDownLatch(1);
		channel.connect(new InetSocketAddress(host, port), channel, new CompletionHandler<Void, AsynchronousSocketChannel>() {

			@Override
			public void completed(Void result, final AsynchronousSocketChannel channel) {
				String order = "Hello AIO";
				byte[] bytes = order.getBytes();
				ByteBuffer readBuffer = ByteBuffer.allocate(bytes.length);
				readBuffer.put(bytes);
				readBuffer.flip();
				channel.write(readBuffer, readBuffer, new CompletionHandler<Integer, ByteBuffer>() {
					@Override
					public void completed(Integer result, ByteBuffer attachment) {
						if (attachment.hasRemaining()) {
							channel.write(attachment, attachment, this);
						} else {
							ByteBuffer readBuffer = ByteBuffer.allocate(1024);
							channel.read(readBuffer, readBuffer, new CompletionHandler<Integer, ByteBuffer>() {
								@Override
								public void completed(Integer result, ByteBuffer attachment) {
									attachment.flip();
									byte[] bytes = new byte[attachment.remaining()];
									attachment.get(bytes);
									String string;
									try {
										string = new String(bytes, "UTF-8");
										logger.info("GET from Server time " + string);
									} catch (UnsupportedEncodingException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
									latch.countDown();
								}

								@Override
								public void failed(Throwable exc, ByteBuffer attachment) {
									logger.error(exc, exc);

								}
							});
						}
					}

					@Override
					public void failed(Throwable exc, ByteBuffer attachment) {
						logger.error(exc, exc);
					}
				});
			}

			@Override
			public void failed(Throwable exc, AsynchronousSocketChannel attachment) {
				logger.error(exc, exc);
				try {
					attachment.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

		});

		try {
			latch.await();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			channel.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}
